﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;
using System.IO.Compression;

namespace DSheet.Core.Data
{
    public class DocTemplate
    {
        public Guid Id { get; set; }
        
        public Guid BYearId { get; set; }
        public Guid BDomainId { get; set; }
        public Guid BOrgId { get; set; }

        public Guid DefId { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public string Version { get; set; }
        public bool IsLatest { get; set; }
        public string Data { get; set; }

        public string Serialize(ComboDim yDim, ComboDim xDim, List<DocDim> pageDims)
        {
            XDocument xDoc = new XDocument();
            XElement xRoot = new XElement("doc");
            xRoot.Add(new XAttribute("id", Id));
            xRoot.Add(new XAttribute("name", this.Name));
            xRoot.Add(new XAttribute("version", Version));

            XElement xyd = new XElement("yd");
            foreach (var dim in yDim)
            {
                XElement xi = new XElement("i");
                xi.Add(new XAttribute("c", dim.DimCode));
                xi.Add(new XAttribute("n", dim.DimName));
                xi.Add(new XAttribute("i", dim.Index));
                xi.Add(new XAttribute("di", dim.DirIndex));
                xi.Add(new XAttribute("p", dim.IsPageDim));

                xyd.Add(xi);
            }
            xRoot.Add(xyd);

            XElement xxd = new XElement("xd");
            foreach (var dim in xDim)
            {
                XElement xi = new XElement("i");
                xi.Add(new XAttribute("c", dim.DimCode));
                xi.Add(new XAttribute("n", dim.DimName));
                xi.Add(new XAttribute("i", dim.Index));
                xi.Add(new XAttribute("di", dim.DirIndex));
                xi.Add(new XAttribute("p", dim.IsPageDim));

                xxd.Add(xi);
            }
            xRoot.Add(xxd);

            xDoc.Add(xRoot);

            string originalData = xDoc.ToString();
            byte[] dataArr = Encoding.UTF8.GetBytes(originalData);
            return Convert.ToBase64String(Compress(dataArr));
        }

        public string SerializeY(List<DRow> yRows)
        {
            XDocument xDoc = new XDocument();
            XElement xYRows = new XElement("y");
            foreach (DRow yRow in yRows)
            {
                XElement xYRow = new XElement("d");
                foreach (DItem dItem in yRow.Items)
                {
                    XElement xYItem = new XElement("i");
                    xYItem.Add(new XAttribute("l", dItem.Level));
                    xYItem.Add(new XAttribute("c", dItem.Code));
                    xYItem.Add(new XAttribute("n", dItem.Name));
                    xYRow.Add(xYItem);
                }
                xYRows.Add(xYRow);
            }
            xDoc.Add(xYRows);

            string originalData = xDoc.ToString();
            byte[] dataArr = Encoding.UTF8.GetBytes(originalData);
            return Convert.ToBase64String(Compress(dataArr));
        }

        public string SerializeX(List<DRow> xRows)
        {
            XDocument xDoc = new XDocument();
            // x-dims
            XElement xXRows = new XElement("x");
            foreach (DRow xRow in xRows)
            {
                XElement xXRow = new XElement("d");
                foreach (DItem dItem in xRow.Items)
                {
                    XElement xXItem = new XElement("i");
                    xXItem.Add(new XAttribute("l", dItem.Level));
                    xXItem.Add(new XAttribute("c", dItem.Code));
                    xXItem.Add(new XAttribute("n", dItem.Name));
                    xXRow.Add(xXItem);
                }
                xXRows.Add(xXRow);
            }
            xDoc.Add(xXRows);

            string originalData = xDoc.ToString();
            byte[] dataArr = Encoding.UTF8.GetBytes(originalData);
            return Convert.ToBase64String(Compress(dataArr));
        }

        private byte[] Compress(byte[] bytes)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                GZipStream Compress = new GZipStream(ms, CompressionMode.Compress);

                Compress.Write(bytes, 0, bytes.Length);

                Compress.Close();

                return ms.ToArray();
            }
        }
    }
}
